package com.dsj.gxrd.modules.book.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsj.gxrd.modules.book.domain.dto.RdBookDto;
import com.dsj.gxrd.modules.book.domain.dto.RdFileDto;
import com.dsj.gxrd.modules.book.domain.entity.RdBook;
import com.dsj.gxrd.modules.book.domain.query.RdBookQuery;
import com.dsj.gxrd.modules.book.domain.vo.RdBookCockpit;
import com.dsj.gxrd.modules.book.enums.FileRelationTypeEnum;
import com.dsj.gxrd.modules.book.mapper.RdBookMapper;
import com.dsj.gxrd.modules.book.service.IRdBookService;
import com.dsj.gxrd.modules.book.service.IRdFileService;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.utils.bean.BeanUtils;
import com.ruoyi.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 【请填写功能名称】Service业务层处理
 *
 * @author ruoyi
 * @date 2023-09-11
 */
@Slf4j
@Service
public class RdBookServiceImpl extends ServiceImpl<RdBookMapper, RdBook> implements IRdBookService {

    @Autowired
    private IRdFileService rdFileService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RdBookMapper rdBookMapper;

    public static final ExecutorService executors=Executors.newScheduledThreadPool(10);

    /**
     * 项目启动时，初始化字典到缓存
     */
    @PostConstruct
    public void init()
    {
        loadingBookCache();
    }

    public void loadingBookCache() {
        List<RdBookDto> rdBookList = rdBookMapper.selectRdBookLists(new RdBookQuery());
        Map<String, RdBookCockpit> dataMap =
                BeanUtils.toMap(rdBookList,item -> item.getRdBookId().toString(),item -> BeanUtils.copyProperties(item, RdBookCockpit.class));
        redisService.setCacheMap(CacheConstants.BOOK_VIEW_COUNT_KEY,dataMap);
    }

    @Override
    public RdBookDto selectRdBookByRdBookId(Long rdBookId) {
        List<RdFileDto> list = rdFileService.listFiles(rdBookId, FileRelationTypeEnum.BOOK_SWEET_RECOMMEND_BOOKS_IMAGE);
        RdBook rdBook = this.baseMapper.selectById(rdBookId);
        RdBookDto rdBookDto = BeanUtils.copyProperties(rdBook, RdBookDto.class);
        rdBookDto.setFileList(list);
        executors.submit(()->{
            cacheBook(rdBook);
            updateById(rdBook);
        });
        return rdBookDto;
    }

    private void cacheBook(RdBook rdBook) {
            Map<String, Object> cacheMap = redisService.getCacheMap(CacheConstants.BOOK_VIEW_COUNT_KEY);
            String idKey = rdBook.getRdBookId().toString();
            RdBookCockpit bookCockpit = new RdBookCockpit();
            bookCockpit.setBookName(rdBook.getBookName());
            if (cacheMap.get(idKey) != null) {
                RdBookCockpit o = (RdBookCockpit) cacheMap.get(idKey);
                bookCockpit.setViewCount(o.getViewCount() + 1);
            } else {
                long viewCount = rdBook.getViewCount() == null ? 0 : rdBook.getViewCount();
                bookCockpit.setViewCount(viewCount + 1);
            }
            rdBook.setViewCount(bookCockpit.getViewCount());
            redisService.setCacheMapValue(CacheConstants.BOOK_VIEW_COUNT_KEY, idKey, bookCockpit);
    }

    @Override
    public List<RdBookDto> selectRdBookList(RdBookQuery rdBook) {
        List<RdBookDto> rdBookList = rdBookMapper.selectRdBookLists(rdBook);
        rdBookList.forEach(item -> {
            List<RdFileDto> fileDtoList =
                    rdFileService.listFiles(item.getRdBookId(), FileRelationTypeEnum.BOOK_SWEET_RECOMMEND_BOOKS_IMAGE);
            item.setFileList(fileDtoList);
        });
        return rdBookList;
    }

    @Override
    public List<RdBookCockpit> cockpit() {
        //获取前三排名的数据
        Map<String, RdBookCockpit> cacheMap = redisService.getCacheMap(CacheConstants.BOOK_VIEW_COUNT_KEY);
        if (cacheMap.isEmpty()) {
            List<RdBookDto> rdBookList = rdBookMapper.selectRdBookLists(new RdBookQuery());
            Map<String, RdBookCockpit> dataMap =
                    BeanUtils.toMap(rdBookList,item -> item.getRdBookId().toString(),item -> BeanUtils.copyProperties(item, RdBookCockpit.class));
            redisService.setCacheMap(CacheConstants.BOOK_VIEW_COUNT_KEY, dataMap);
            int index = rdBookList.size() > 2 ? 3 : rdBookList.size();
            return rdBookList.stream().map(item -> BeanUtils.copyProperties(item, RdBookCockpit.class)).sorted(Comparator.comparing(RdBookCockpit::getViewCount, (o1, o2) -> (int) (o2 - o1)))
                    .collect(Collectors.toList()).subList(0, index);
        }
        int index = cacheMap.values().size() > 2 ? 3 : cacheMap.values().size();
        return cacheMap.values().stream().sorted(Comparator.comparing(RdBookCockpit::getViewCount, (o1, o2) -> (int) (o2 - o1)))
                .collect(Collectors.toList()).subList(0, index);
    }


}
